package cn.klaw.i18n.core;

import cn.hutool.core.util.ReflectUtil;
import cn.klaw.i18n.provider.MessageSourceProvider;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;

import java.io.IOException;
import java.io.StringReader;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.concurrent.ConcurrentMap;

/**
 * 本地动态消息来源
 *
 *
 * @user N
 *
 * @date 2024/3/21 14:00
 */
@Slf4j
public class MyReloadableResourceBundleMessageSource extends ReloadableResourceBundleMessageSource {



    @Getter
    private final ConcurrentMap<String, PropertiesHolder> cachedPropertiesCopy;

    @Getter
    private final ConcurrentMap<Locale, PropertiesHolder> cachedMergedPropertiesCopy;

    private List<MessageSourceProvider> messageSourceProviders;

    public MyReloadableResourceBundleMessageSource(List<MessageSourceProvider> messageSourceProviders) {
        this.messageSourceProviders = messageSourceProviders;
        cachedPropertiesCopy = (ConcurrentMap<String, PropertiesHolder>) ReflectUtil.getFieldValue(this, "cachedProperties");
        cachedMergedPropertiesCopy = (ConcurrentMap<Locale, PropertiesHolder>) ReflectUtil.getFieldValue(this, "cachedMergedProperties");
    }


    @Override
    protected PropertiesHolder refreshProperties(String filename, PropertiesHolder propHolder) {
        propHolder = super.refreshProperties(filename, propHolder);
        // 本地未获取到语言翻译文件, 从自定义来源获取
        if (propHolder.getProperties() == null && messageSourceProviders != null) {
            for (MessageSourceProvider messageSourceProvider : messageSourceProviders) {
                try {
                    String config = messageSourceProvider.loadMessageResource(filename, this);
                    if (config != null) {
                        propHolder = refreshConfig(filename, config);
                        break;
                    }
                } catch (Exception e) {
                    log.error("加载语言配置失败：{}, {}", filename, e.getMessage(), e);
                }
            }
        }
        return propHolder;
    }

    /**
     * 刷新语言配置文件
     * @param filename 语言文件
     * @param config properties内容
     * @throws IOException
     */
    public PropertiesHolder refreshConfig(String filename, String config) throws IOException {
        long refreshTimestamp = (getCacheMillis() < 0 ? -1 : System.currentTimeMillis());
        Properties properties = new Properties();
        properties.load(new StringReader(config));
        PropertiesHolder propertiesHolder = new PropertiesHolder(properties, refreshTimestamp);
        propertiesHolder.setRefreshTimestamp(refreshTimestamp);
        this.cachedPropertiesCopy.put(filename, propertiesHolder);
        this.cachedMergedPropertiesCopy.clear();
        return propertiesHolder;
    }

    /**
     * 更新某个语言中的配置
     *
     * @param filename 语言文件
     * @param property 语言标识符
     * @param value    语言内容
     */
    public void refreshConfig(String filename, String property, String value) {
        PropertiesHolder propertiesHolder = cachedPropertiesCopy.get(filename);
        Properties properties = propertiesHolder.getProperties();
        if (properties != null) {
            properties.setProperty(property, value);
            this.cachedMergedPropertiesCopy.clear();
        }
    }
}
